/**
 * Parser.java	1.0 2007 六月 1 17:16:42,创建
 */

package org.in4j.search.query.parser;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.lucene.search.Query;
import org.in4j.search.query.IQuery;

/**
 *
 * @author 杨帆
 * @version 1.0 2007 六月 1 17:16:42,创建
 */
public class Parser
{
	@SuppressWarnings("unused")
	private static final Log log = LogFactory.getLog(Parser.class);

	public Query parse(String queryString)
	{
		final List<MyToken> list = getPostSuffixTokens(queryString);
		System.out.println("list====>\n\t" + list);
		final List<MyToken> operands = new ArrayList<MyToken>();
		final LinkedList<IQuery> queries = new LinkedList<IQuery>();
		for(MyToken token: list)
		{
			System.out.println("token:" + token);
			if(token.isVar())
			{
				operands.add(token);
			}
			if(token.isOperator())
			{
				IQuery query = getOperatorQuery(token.getValue(),operands.get(0),operands.get(1));
				System.out.println("--->" + query);
				operands.clear();
				queries.add(query);
			}
			if(token.isRelation())
			{
				IQuery query = getRelationQuery(token.getValue(),queries.poll(),queries.poll());
				System.out.println("--->" + query);
				queries.add(query);
			}
		}
		System.out.println("queries==>" + queries);
		Query myquery = queries.peek().getQuery();
		System.out.println("jjjjjjjjjjjjj==>" + myquery);
		return myquery;
//		throw new UnsupportedOperationException("未完成该功能.");
	}

	private IQuery getRelationQuery(String value, IQuery query1, IQuery query2)
	{
		String className;
		if("and".equals(value))
		{
			className = "org.in4j.search.query.And";
		}
		else if("or".equals(value))
		{
			className = "org.in4j.search.query.Or";
		}
		else
		{
			throw new IllegalStateException("不支持的操作符:" + value);
		}
		try
		{
			Class clz = Class.forName(className);
			IQuery query = (IQuery)clz.getConstructors()[0].newInstance(new Object[]{query1,query2});
			return query;
		}
		catch(Exception e)
		{
			e.printStackTrace();
			throw new RuntimeException("----------");
		}
	}

	private IQuery getOperatorQuery(String value, MyToken token, MyToken token2)
	{
		String className;
		if("like".equals(value))
		{
			className = "org.in4j.search.query.Like";
		}
		else if("=".equals(value))
		{
			className = "org.in4j.search.query.Equal";
		}
		else
		{
			throw new IllegalStateException("不支持的操作符:" + value);
		}
		try
		{
			Class clz = Class.forName(className);
			IQuery query = (IQuery)clz.getConstructors()[0].newInstance(new Object[]{token.getValue(),token2.getValue()});
			return query;
		}
		catch(Exception e)
		{
			e.printStackTrace();
			throw new RuntimeException("----------");
		}
	}

	private List<MyToken> getPostSuffixTokens(String queryString)
	{
		final LinkedList<MyToken> stack = new LinkedList<MyToken>();
		final List<MyToken> out = new ArrayList<MyToken>();
		for(MyToken token : parseToIterator(queryString))
		{
//			System.out.println("token:" + token);
			do
			{
				if(token.isOperator() || token.isRelation())
				{
					while(!stack.isEmpty())
					{
						MyToken op = stack.peek();
						if(op.isPreBracket()) break;
						if(op.getLevel() < token.getLevel()) break;
						out.add(op);
						stack.removeFirst();
					}
					stack.addFirst(token);
					break;
				}
				if(token.isPreBracket())
				{
					stack.addFirst(token);
					break;
				}
				if(token.isPostBracket())
				{
					while(!stack.isEmpty())
					{
						MyToken op = stack.poll();
						if(op.isPreBracket())
							break;
						else
							out.add(op);
					}
					break;
				}
				out.add(token);
			}while(false);
		}
		while(!stack.isEmpty())
		{
			out.add(stack.poll());
		}
//		Collections.reverse(out);	//prefix
//		System.out.println("out====>\n\t" + out);
		return out;
	}

	private Iterable<MyToken> parseToIterator(final String queryString)
	{
		return new Iterable<MyToken>()
		{

			public Iterator<MyToken> iterator()
			{
				return new MyTokenIterator(queryString);
			}
		};
	}

	private char get(String ch)
	{
		// TODO 自动生成方法存根
		if(true)
			throw new UnsupportedOperationException();
		return 0;
	}
}
